/*
 * @Author: zhangyang
 * @Date: 2022-03-01 14:01:31
 * @LastEditTime: 2022-03-06 14:39:15
 * @Description: 网络请求
 */
import axios from 'axios';
import type { Method } from 'axios';
import type { ResponseObj, UserModule } from '@/typings/type';
import { Status } from '@/typings/type';
import { useLoadingStore } from '@/stores';
import { getToken, removeToken } from '@/stores/cookie/loginInfo';

/**
 * 创建 Axios 实例
 */
const net = axios.create({
  baseURL: import.meta.env.VITE_BASE_HTTP,
  timeout: 1000 * 5
});
type ParamsObj = Record<string, any>;
/**
 * 不需要 token 的请求，默认 post 请求
 */
export const requestWithoutToken = (param: ParamsObj, method: Method = 'post') => {
  const data = new FormData();
  for (const [key, value] of Object.entries(param)) {
    data.append(key, value);
  }
  return net({
    method: 'post',
    data
  }) as unknown as Promise<any>;
};
/**
 * 需要 token 的普通请求
 */
export const basicRequest = (param: ParamsObj) => {
  const { token, aid } = getToken();
  param['token'] = token;
  param['aid'] = aid;
  return requestWithoutToken(param);
};
/**
 * 文件上传
 */
export const upload = (param: ParamsObj, formData: FormData) => {
  const { token, aid } = getToken();
  param['token'] = token;
  param['aid'] = aid;
  for (const [key, value] of Object.entries(param)) {
    formData.append(key, value);
  }
  return net({
    method: 'post',
    data: formData
  }) as unknown as Promise<any>;
};

export const install: UserModule = (ctx) => {
  const { httpPending } = storeToRefs(useLoadingStore());
  /**
   * 设置请求拦截器
   */
  net.interceptors.request.use((req) => {
    httpPending.value = true;
    return req;
  }, (error) => {
    console.error(error);
    window.$message.error(error);
    return Promise.reject(error);
  });

  /**
   * 设置响应拦截器
   */
  net.interceptors.response.use((response) => {
    httpPending.value = false;
    const res = response.data as ResponseObj;
    if (res.status === Status.OK) {
      return res.data;
    } else if (res.status === Status.TOKEN_NO_USE) {
      // 登录过期
      removeToken();
      location.reload();
    } else {
      const error = res.msg;
      window.$message.error(error);
      throw new Error(error);
    }
  }, (error: Error) => {
    httpPending.value = false;
    console.error(error);
    window.$message.error(error.message);
    throw new Error(error.message);
  });
};